package model.playable;
import model.command.*;
import model.playable.unit.*;
import model.map.*;
import java.util.*;
import model.visibility.*;
import model.mapping.*;

public class RallyPoint extends Playable implements MoveWorkerable, Prospectable, Combatable, Moveable, Constructable, Buildable
{
	private Unit[] army;
	private int groupMovementSpeed;
	private int groupRange;
	
	public RallyPoint(PlayableUser player)
	{
		setPlayer(player);
		setIdNumber(-1);
		setUpkeep(1);
		setInfluenceRadius(0);
		setVisibilityRadius(1);
		setCommandQueue(new LinkedList<Command>());
		setCommandsPossibleList(createCommandPossibleList());
		setCurrentPossibleCommandPosition(0);
		setIsInStandBy(false);
		setIsPoweredDown(false);
		setArmy(new Unit[10]);
		setGroupMovementSpeed(0);
		setGroupRange(0);
	}
	
	public LinkedList<Command> createCommandPossibleList()
	{
		LinkedList<Command> possibleCommands = new LinkedList<Command>();
		possibleCommands.add(new BuildFort(this));
		possibleCommands.add(new BuildFarm(this));
		possibleCommands.add(new BuildMine(this));
		possibleCommands.add(new BuildPowerPlant(this));
		possibleCommands.add(new BuildUniversity(this));
		possibleCommands.add(new BuildObservationTower(this));
		possibleCommands.add(new PowerDown(this));
		possibleCommands.add(new PowerUp(this));
		possibleCommands.add(new Decommission(this));
		possibleCommands.add(new Standby(this));
		possibleCommands.add(new Prospect(this));
		possibleCommands.add(new Attack(this));
		possibleCommands.add(new Defend(this));
		possibleCommands.add(new Move(this));
		return possibleCommands;
	} 
	
	public void addToCommandQueue(Command command)
	{
		if(checkCommandsPossibleList(command) && !getIsPoweredDown())
		{
			getCommandQueue().add(command);
			for(int i = 0; i < army.length; i++)
			{
				army[i].addToCommandQueue(command);
			}
		}
		else
		{
			getCommandQueue().add(new Standby(this));
		}
	}
	
	public Unit[] getArmy()
	{
		return army;
	}
	
	public void setArmy(Unit[] army)
	{
		this.army = army;
	}
	
	public void setLocation(int x, int y)
	{
		int[] location2 = new int[] {x,y};
	}
	
	public int getGroupMovementSpeed()
	{
		return groupMovementSpeed;
	}
	
	public void setGroupMovementSpeed(int groupMovementSpeed)
	{
		this.groupMovementSpeed = groupMovementSpeed;
	}
	
	public int getGroupRange()
	{
		return groupRange;
	}
	
	public void setGroupRange(int groupRange)
	{
		this.groupRange = groupRange;
	}
	
	public void incrementGroupMovementSpeed(int increment)
	{
		groupMovementSpeed += increment;
	}
	
	public void incrementGroupRange(int increment)
	{
		groupRange += increment;
	}
	
	public void addArmyUnit(Unit unit)
	{
		for(int i = 0; i < army.length ; i++)
		{
			if(army[i] == null)
			{
				army[i] = unit;
				unit.setArmyId(i);
				break;
			}
		}
	}
		
	public void removeArmyUnit(int id)
	{
		army[id] = null;
	}
	
	public Worker[] getWorkers(int amount)
	{
		//todo
		return null;
	}
	
	public void attack(Direction direction)
	{
		System.out.println("This rally point added attack " + direction.toString());
	}
	
	public void defend(Direction direction)
	{
		System.out.println("This rally point added defend " + direction.toString());
	}
	
	public void move(Direction direction)
	{
		PlayableMapping map = PlayableMapping.getPlayableMapping();
		map.addRallyPoint(map.getLocationOfRallyPoint(this).getNeighborAt(direction), this);
		map.removeRallyPoint(this);
		System.out.println("This rally point added move " + direction.toString());
	}
	
	public void prospect()
	{
		System.out.println("This rally point added prospect" );
	}
	
	public void dropOffWorkers(int amount)
	{
		System.out.println("This rally point added drop off" );
	}
	
	public void pickUpWorkers(int amount)
	{
		System.out.println("This rally point added pick up" );
	}
	
	public void buildFort(int numWorkers)
	{
		System.out.println("This rally point added build fort" );
	}
	
	public void buildFarm(int numWorkers)
	{
		System.out.println("This rally point added build farm" );
	}
	
	public void buildPowerPlant(int numWorkers)
	{
		System.out.println("This rally point added build power plant" );
	}
	
	public void buildMine(int numWorkers)
	{
		System.out.println("This rally point added build mine" );
	}
	
	public void buildObservationTower(int numWorkers)
	{
		System.out.println("This rally point added build observation tower" );
	}
	
	public void buildUniversity(int numWorkers)
	{
		System.out.println("This rally point added build university" );
	}
	
	public void constructCapital()
	{
		System.out.println("This rally point added construct capital" );
	}
	
	public void powerUp()
	{
		System.out.println("This rally point added power up" );
	}
	
	public void powerDown()
	{
		System.out.println("This rally point added power down" );
	}
	
	public void decommission()
	{
		System.out.println("This rally point added decommission" );
	}
	
	public void standBy()
	{
		System.out.println("This rally point added stand by" );
	}
	
	public void accept(PlayableVisitor pv)
	{
		pv.visitRallyPoint(this);
	}
	
	public void takeDamage(int a)
	{
		for(int i = 0; i < army.length ; i++)
		{
			if(army[i] != null)
			{
				army[i].takeDamage(a);
			}
		}
	}
	
	public void heal(int a)
	{
		for(int i = 0; i < army.length ; i++)
		{
			if(army[i] != null)
			{
				army[i].heal(a);
			}
		}
	}
	
	public GameTile getLocation()
	{
		return PlayableMapping.getPlayableMapping().getLocationOfRallyPoint(this);
	}
	
	public String toString()
	{
		return "Rally Point";
	}
}